home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / Pascal / Applications / NIH Image 1.62b11 / src / Text.p < prev    next >
Text File  |  1996-03-01  |  19KB  |  719 lines

  1. unit text;
  2. {This unit contains routines for opening, saving, scrolling and editing text windows.}
  3.  
  4. interface
  5.  
  6.     uses
  7.         Types, Memory, QuickDraw, QuickDrawText, Packages, Menus, Events, Fonts, 
  8.         Scrap, ToolUtils, Resources, Errors, Palettes, StandardFile, Windows,
  9.         Controls, TextEdit, Files, Dialogs, TextUtils, Finder, MixedMode,
  10.         globals, Utilities, Graphics, File2;
  11.  
  12.     procedure UpdateScrollBars;
  13.     procedure UpdateTextWindow (WhichWindow: WindowPtr);
  14.     procedure ActivateTextWindow (WhichWindow: WindowPtr; Activating: boolean);
  15.     procedure DoMouseDownInText (event: EventRecord; WhichWindow: WindowPtr);
  16.     procedure ScrollText;
  17.     procedure GrowTextWindow (NewSize: LongInt);
  18.     function MakeNewTextWindow (name: str255; width, height: integer): boolean;
  19.     function OpenTextFile (name: str255; RefNum: integer): boolean;
  20.     procedure DoKeyDownInText (ch: char);
  21.     procedure ChangeFontOrSize;
  22.     procedure DoTextCopy;
  23.     procedure DoTextPaste;
  24.     procedure DoTextClear;
  25.     procedure SaveText;
  26.     procedure SaveTextAs;
  27.     function SaveTextChanges: integer;
  28.     procedure InsertText (str: str255; EndOfLine: boolean);
  29.     procedure DoFind;
  30.     procedure DecrementTextWindowNums (num: integer);
  31.     procedure SaveTextUsingPath (name:str255);
  32.     procedure SelectAllText;
  33.  
  34.  
  35. implementation
  36.  
  37.  
  38.     type
  39.         CharArrayType = packed array[0..32767] of char;
  40.         CharArrayPtr = ^CharArrayType;
  41.  
  42.  
  43.     procedure UpdateScrollBars;
  44.         var
  45.             vMax, vValue, hMax, hValue: integer;
  46.     begin
  47.         with TextInfo^ do begin
  48.                 hlock(handle(TextTE));
  49.                 with TextTE^^, TextTE^^.viewRect do begin
  50.                         vTextPageSize := (bottom - top) div LineHeight;
  51.                         hTextPageSize := right - left;
  52.                         vMax := nLines - vTextPageSize;
  53.                         hMax := 0;
  54.                         vValue := (top - destRect.top) div LineHeight;
  55.                         hValue := left - destRect.left;
  56.                         if vMax < 0 then
  57.                             vMax := 0;
  58.                         if vValue < 0 then
  59.                             vValue := 0;
  60.                         if hMax < 0 then
  61.                             hMax := 0;
  62.                         if vValue < 0 then
  63.                             vValue := 0;
  64.                         SetControlMaximum(vTextScrollBar, vMax);
  65.                         SetControlValue(vTextScrollBar, vValue);
  66.                         SetControlMaximum(hTextScrollBar, hMax);
  67.                         SetControlValue(hTextScrollBar, hValue);
  68.                     end;
  69.                 hunlock(handle(TextTE));
  70.             end;
  71. {ShowMessage(concat('nListColumns= ', Long2str(nListColumns), crStr, 'hListPageSize= ', long2str(hListPageSize)));}
  72.     end;
  73.  
  74.  
  75.     procedure SetTextInfo;
  76.   {Updates TextInfo so it points to the active text window.}
  77.         var
  78.             kind: integer;
  79.     begin
  80.         kind := CurrentWindow;
  81.     end;
  82.  
  83.  
  84.     procedure UpdateTextWindow (WhichWindow: WindowPtr);
  85.     begin
  86.         TextInfo := TextInfoPtr(WindowPeek(WhichWindow)^.RefCon);
  87.         if TextInfo <> nil then
  88.             with TextInfo^ do begin
  89.                     SetPort(TextWindowPtr);
  90.                     DrawControls(TextWindowPtr);
  91.                     DrawGrowIcon(TextWindowPtr);
  92.                     EraseRect(TextTE^^.viewRect);
  93.                     TEUpdate(TextTE^^.viewRect, TextTE);
  94.                     UpdateScrollBars;
  95.                 end; {with}
  96.         SetTextInfo;
  97.     end;
  98.  
  99.  
  100.     procedure ActivateTextWindow (WhichWindow: WindowPtr; Activating: boolean);
  101.     begin
  102.         if Activating then
  103.             UpdateTextWindow(WhichWindow);
  104.         TextInfo := TextInfoPtr(WindowPeek(WhichWindow)^.RefCon);
  105.         if TextInfo <> nil then
  106.             with TextInfo^ do
  107.                 if Activating then begin
  108.                         TEActivate(TextTE);
  109.                         ShowControl(hTextScrollBar);
  110.                         ShowControl(vTextScrollBar);
  111.                         WhatToUndo := NothingToUndo;
  112.                     end
  113.                 else begin
  114.                         TEDeactivate(TextTE);
  115.                         HideControl(hTextScrollBar);
  116.                         HideControl(vTextScrollBar);
  117.                     end;
  118.         SetTextInfo;
  119.     end;
  120.  
  121.  
  122.     procedure SetFontSize;
  123.         var
  124.             fInfo: FontInfo;
  125.     begin
  126.         with TextInfo^ do begin
  127.                 SetPort(TextWindowPtr);
  128.                 TextFont(CurrentFontID);
  129.                 TextSize(CurrentSize);
  130.                 with TextTE^^, fInfo do begin
  131.                         GetFontInfo(fInfo);
  132.                         TxSize := CurrentSize;
  133.                         LineHeight := ascent + descent + leading;
  134.                         FontAscent := ascent;
  135.                     end;
  136.             end;
  137.     end;
  138.  
  139.  
  140.     procedure InitTextEdit;
  141.         var
  142.             dRect, vRect: rect;
  143.     begin
  144.         with TextInfo^ do begin
  145.                 SetPort(TextWindowPtr);
  146.                 SetRect(vrect, 0, 0, TextWidth - ScrollBarWidth, TextHeight - ScrollBarWidth);
  147.                 drect := vrect;
  148.                 InsetRect(drect, 4, 4);
  149.                 TextTE := TENew(drect, vrect);
  150.                 with TextTE^^ do begin
  151.                         TxFont := CurrentFontID;
  152.                         SetFontSize;
  153.                         crOnly := 1; {do word wrap}
  154.                     end;
  155.                 TESetSelect(0, 0, TextTE);
  156.                 UpdateScrollBars;
  157.                 TEAutoView(true, TextTE); {Enable auto-scrolling}
  158.             end;
  159.     end;
  160.  
  161.  
  162.     procedure ScrollText;
  163.         var
  164.             value: integer;
  165.     begin
  166.         with TextInfo^, TextInfo^.TextTE^^ do
  167.             TEScroll(0, (viewRect.top - destRect.top) - (GetControlValue(vTextScrollBar) * LineHeight), TextTE);
  168.     end;
  169.  
  170.  
  171.     procedure ScrollAction (theCtl: ControlHandle; partCode: integer);
  172.         var
  173.             bInc, pInc, delta: integer;
  174.     begin
  175.         if TextInfo <> nil then
  176.             with TextInfo^ do begin
  177.                     if theCtl = vTextScrollBar then begin
  178.                             bInc := 1;
  179.                             pInc := vTextPageSize
  180.                         end
  181.                     else begin
  182.                             bInc := 4;
  183.                             pInc := hTextPageSize
  184.                         end;
  185.                     case partCode of
  186.                         kControlUpButtonPart: 
  187.                             delta := -bInc;
  188.                         kControlDownButtonPart: 
  189.                             delta := bInc;
  190.                         kControlPageUpPart: 
  191.                             delta := -pInc;
  192.                         kControlPageDownPart: 
  193.                             delta := pInc;
  194.                         otherwise
  195.                             exit(ScrollAction);
  196.                     end;
  197.                     SetControlValue(theCtl, GetControlValue(theCtl) + delta);
  198.                     ScrollText;
  199.                 end; {with}
  200.     end;
  201.  
  202.  
  203.     procedure DoMouseDownInText (event: EventRecord; WhichWindow: WindowPtr);
  204.         var
  205.             theCtl: ControlHandle;
  206.             cValue: integer;
  207.             loc: point;
  208.     begin
  209.         TextInfo := TextInfoPtr(WindowPeek(WhichWindow)^.RefCon);
  210.         if TextInfo = nil then
  211.             exit(DoMouseDownInText);
  212.         SelectWindow(WhichWindow);
  213.         SetPort(WhichWindow);
  214.         loc := event.where;
  215.         GlobalToLocal(loc);
  216.         with TextInfo^ do
  217.             if PtInRect(loc, TextTE^^.viewRect) then begin
  218.                     TEClick(loc, BitTst(@event.modifiers, 6), TextTE);
  219.                     UpdateScrollBars;
  220.                 end
  221.             else
  222.                 case FindControl(loc, WhichWindow, theCtl) of
  223.                     kControlUpButtonPart, kControlDownButtonPart, kControlPageUpPart, kControlPageDownPart: 
  224.                         if TrackControl(theCtl, loc, TextScrollActionProc) <> 0 then
  225.                             ;
  226.                     kControlIndicatorPart: 
  227.                         if TrackControl(theCtl, loc, nil) <> 0 then
  228.                             ScrollText;
  229.                     otherwise
  230.                 end;
  231.     end;
  232.  
  233.  
  234.     procedure GrowTextWindow (NewSize: LongInt);
  235.     begin
  236.         if TextInfo <> nil then
  237.             with TextInfo^ do begin
  238.                     TextWidth := LoWrd(NewSize);
  239.                     TextHeight := HiWrd(NewSize);
  240.                     SetPort(TextWindowPtr);
  241.                     SizeWindow(TextWindowPtr, TextWidth, TextHeight, true);
  242.                     EraseRect(TextWindowPtr^.PortRect);
  243.                     MoveControl(hTextScrollBar, -1, TextHeight - ScrollBarWidth);
  244.                     MoveControl(vTextScrollBar, TextWidth - ScrollBarWidth, -1);
  245.                     SizeControl(hTextScrollBar, TextWidth - 13, ScrollBarWidth + 1);
  246.                     SizeControl(vTextScrollBar, ScrollBarWidth + 1, TextHeight - 13);
  247.                     InvalRect(TextWindowPtr^.PortRect);
  248.                     with TextTE^^ do begin
  249.                             SetRect(viewRect, 0, 0, TextWidth - ScrollBarWidth, TextHeight - ScrollBarWidth);
  250.                             viewRect.bottom := (viewRect.bottom div lineHeight) * lineHeight;
  251.                             destRect := viewRect;
  252.                             InsetRect(destRect, 4, 4);
  253.                         end;
  254.                     TECalText(TextTE);
  255.                     ScrollText;
  256.                 end; {with}
  257.     end;
  258.  
  259.  
  260.     function MakeNewTextWindow (name: str255; width, height: integer): boolean;
  261.         var
  262.             wrect, crect: rect;
  263.     begin
  264.         MakeNewTextWindow := false;
  265.         if nTextWindows >= MaxTextWindows then begin
  266.                 PutError(concat('NIH Image cannot open more than ', long2str(MaxTextWindows), ' text windows.'));
  267.                 exit(MakeNewTextWindow);
  268.             end;
  269.         TextInfo := TextInfoPtr(NewPtr(SizeOf(TextInfoRec)));
  270.         if TextInfo = nil then
  271.             exit(MakeNewTextWindow);
  272.         with TextInfo^ do begin
  273.                 TextWidth := width;
  274.                 TextHeight := height;
  275.                 TextLeft := PicLeft;
  276.                 TextTop := PicTop;
  277.                 PicLeft := PicLeft + hPicOffset;
  278.                 PicTop := PicTop + vPicOffset;
  279.                 if ((PicLeft + TextWidth) > ScreenWidth) or ((PicTop + TextHeight) > ScreenHeight) then begin
  280.                         PicLeft := PicLeftBase;
  281.                         PicTop := PicTopBase;
  282.                     end;
  283.                 if (TextTop + TextHeight) > ScreenHeight then
  284.                     TextHeight := ScreenHeight - TextTop - 4;
  285.                 SetRect(wrect, TextLeft, TextTop, TextLeft + TextWidth, TextTop + TextHeight);
  286.                 TextWindowPtr := NewWindow(nil, wrect, name, true, 0, pointer(-1), true, 0);
  287.                 if TextWindowPtr = nil then begin
  288.                         DisposePtr(ptr(TextInfo));
  289.                         TextInfo := nil;
  290.                         exit(MakeNewTextWindow);
  291.                     end;
  292.                 WindowPeek(TextWindowPtr)^.WindowKind := TextKind;
  293.                 WindowPeek(TextWindowPtr)^.RefCon := LongInt(TextInfo);
  294.                 SetRect(crect, TextWidth - ScrollBarWidth, -1, TextWidth + 1, TextHeight - 14);
  295.                 vTextScrollBar := NewControl(TextWindowPtr, crect, '', true, 0, 0, TextHeight - 14, ScrollBarProc, 0);
  296.                 SetRect(crect, -1, TextHeight - ScrollBarWidth, TextWidth - 14, TextHeight + 1);
  297.                 hTextScrollBar := NewControl(TextWindowPtr, crect, '', true, 0, 0, TextWidth - 14, ScrollBarProc, 0);
  298.                 InitTextEdit;
  299.                 DrawControls(TextWindowPtr);
  300.                 WhatToUndo := NothingToUndo;
  301.                 TextTitle := name;
  302.                 TextRefNum := 0;
  303.                 Changes := false;
  304.                 TooBig := false;
  305.                 InsertMenuItem(WindowsMenuH, 'Dummy', WindowsMenuItems - 1 + nTextWindows);
  306.                 SetMenuItemText(WindowsMenuH, WindowsMenuItems + nTextWindows, name);
  307.                 nTextWindows := nTextWindows + 1;
  308.                 WindowNum := nTextWindows;
  309.                 TextWindow[nTextWindows] := TextWindowPtr;
  310.                 if TextScrollActionProc=nil
  311.                     {then TextScrollActionProc:=NewControlActionProc(@ScrollAction);} {ppc-bug}
  312.                     then TextScrollActionProc:=NewRoutineDescriptor(@ScrollAction, uppControlActionProcInfo, GetCurrentISA);
  313.                 MakeNewTextWindow := true;
  314.             end; {with}
  315.     end;
  316.  
  317.  
  318.     function OpenTextFile (name: str255; RefNum: integer): boolean;
  319.         var
  320.             err: OSErr;
  321.             f, item: integer;
  322.             TextFileSize: LongInt;
  323.             LargerThan32K: boolean;
  324.     begin
  325.         OpenTextFile := false;
  326.         if FreeMem < MinFree then begin
  327.                 PutError('Not enough memory to open this text file.');
  328.                 exit(OpenTextFile);
  329.             end;
  330.         LargerThan32K := false;
  331.         err := FSOpen(name, RefNum, f);
  332.         err := GetEof(f, TextFileSize);
  333.         if TextFileSize > MaxTextBufSize then begin
  334.                 item := PutMessageWithCancel('This text file is larger than 32K. Would you like to to open the first 32K?');
  335.                 if item = cancel then begin
  336.                         err := fsclose(f);
  337.                         exit(OpenTextFile);
  338.                     end
  339.                 else begin
  340.                         TextFileSize := 30000;
  341.                         LargerThan32K := true;
  342.                     end;
  343.             end;
  344.         if not MakeNewTextWindow(name, 500, 400) then begin
  345.                 err := fsclose(f);
  346.                 exit(OpenTextFile);
  347.             end;
  348.         with TextInfo^ do begin
  349.                 SetHandleSize(TextTE^^.hText, TextFileSize);
  350.                 if MemError <> noErr then begin
  351.                         err := fsclose(f);
  352.                         PutError('Out of memory.');
  353.                         DisposePtr(ptr(TextInfo));
  354.                         TextInfo := nil;
  355.                         exit(OpenTextFile);
  356.                     end;
  357.                 err := SetFPos(f, fsFromStart, 0);
  358.                 ShowWatch;
  359.                 TextTE^^.teLength := TextFileSize;
  360.                 err := fsRead(f, TextFileSize, TextTE^^.hText^);
  361.                 if err <> noErr then begin
  362.                         TextTE^^.teLength := 0;
  363.                         SetHandleSize(TextTE^^.hText, 0);
  364.                         err := fsclose(f);
  365.                         exit(OpenTextFile);
  366.                     end;
  367.                 TECalText(TextTE);
  368.                 TextTitle := name;
  369.                 TextRefNum := RefNum;
  370.                 TooBig := LargerThan32K;
  371.             end; {with}
  372.         err := fsclose(f);
  373.         OpenTextFile := true;
  374.     end;
  375.  
  376.  
  377.     procedure DoKeyDownInText (ch: char);
  378.     begin
  379.         if TextInfo <> nil then begin
  380.                 TEKey(ch, TextInfo^.TextTE);
  381.                 TextInfo^.Changes := true;
  382.                 UpdateScrollBars;
  383. {with TextInfo^ do ShowMessage(concat(long2str(TextTE^^.teLength), '  ', long2str(GetHandleSize(TextTE^^.hText))));}
  384.                 WhatToUndo := NothingToUndo;
  385.             end;
  386.     end;
  387.  
  388.  
  389.     procedure ChangeFontOrSize;
  390.     begin
  391.         if TextInfo <> nil then
  392.             with TextInfo^ do begin
  393.                     TextTE^^.TxFont := CurrentFontID;
  394.                     SetFontSize;
  395.                     SetPort(TextWindowPtr);
  396.                     EraseRect(TextTE^^.viewRect);
  397.                     TEUpdate(TextTE^^.viewRect, TextTE);
  398.                     UpdateScrollBars;
  399.                 end; {with}
  400.     end;
  401.  
  402.  
  403.     procedure DoTextCopy;
  404.         var
  405.             err: OSErr;
  406.     begin
  407.         if TextInfo <> nil then begin
  408.                 TECopy(TextInfo^.TextTE);
  409.                 err := ZeroScrap;
  410.                 if err = NoErr then begin
  411.                         err := TEToScrap;
  412.                         WhatsOnClip := NothingOnClip; {It is on System Scrap}
  413.                     end;
  414.             end;
  415.     end;
  416.  
  417.  
  418.     procedure DoTextPaste;
  419.         var
  420.             err: OSErr;
  421.     begin
  422.         if TextInfo <> nil then begin
  423.                 err := TEFromScrap;
  424.                 if err = NoErr then
  425.                     TEPaste(TextInfo^.TextTE);
  426.                 TextInfo^.Changes := true;
  427.                 UpdateScrollBars;
  428.                 WhatToUndo := NothingToUndo;
  429.             end;
  430.     end;
  431.  
  432.  
  433.     procedure DoTextClear;
  434.         var
  435.             err: OSErr;
  436.     begin
  437.         if TextInfo <> nil then begin
  438.                 TEDelete(TextInfo^.TextTE);
  439.                 TextInfo^.Changes := true;
  440.             end;
  441.         UpdateScrollBars;
  442.         WhatToUndo := NothingToUndo;
  443.     end;
  444.  
  445.  
  446.     procedure DoSaveText;
  447.         var
  448.             err, f: integer;
  449.             TheInfo: FInfo;
  450.             ByteCount: LongInt;
  451.     begin
  452.         if TextInfo <> nil then
  453.             with TextInfo^ do begin
  454.                     hlock(handle(TextTE));
  455.                     with TextTE^^ do begin
  456.                             ByteCount := TELength;
  457.                             if ByteCount = 0 then
  458.                                 exit(DoSaveText);
  459.                             err := GetFInfo(TextTitle, TextRefNum, TheInfo);
  460.                             case err of
  461.                                 NoErr: 
  462.                                     if TheInfo.fdType <> 'TEXT' then begin
  463.                                             TypeMismatch(TextTitle);
  464.                                             exit(DoSaveText)
  465.                                         end;
  466.                                 FNFerr:  begin
  467.                                         err := create(TextTitle, TextRefNum, 'Imag', 'TEXT');
  468.                                         if CheckIO(err) <> 0 then
  469.                                             exit(DoSaveText);
  470.                                     end;
  471.                                 otherwise
  472.                                     if CheckIO(err) <> 0 then
  473.                                         exit(DoSaveText)
  474.                             end;
  475.                             ShowWatch;
  476.                             err := fsopen(TextTitle, TextRefNum, f);
  477.                             if CheckIO(err) <> 0 then
  478.                                 exit(DoSaveText);
  479.                             err := fswrite(f, ByteCount, hText^);
  480.                             if CheckIO(err) <> 0 then
  481.                                 exit(DoSaveText);
  482.                             err := SetEof(f, ByteCount);
  483.                             err := fsclose(f);
  484.                             err := FlushVol(nil, TextRefNum);
  485.                             Changes := false;
  486.                         end; {with}
  487.                     hunlock(handle(TextTE));
  488.                 end; {with}
  489.     end;
  490.  
  491.  
  492.     procedure SaveTextAs;
  493.         var
  494.             where: Point;
  495.             reply: SFReply;
  496.     begin
  497.         if TextInfo <> nil then begin
  498.                 where.v := 60;
  499.                 where.h := 100;
  500.                 SFPutFile(where, 'Save Text as?', TextInfo^.TextTitle, nil, reply);
  501.                 if reply.good then
  502.                     with reply, TextInfo^ do begin
  503.                             TextTitle := fname;
  504.                             TextRefNum := vRefNum;
  505.                             DoSaveText;
  506.                             SetWTitle(TextWindowPtr, TextTitle);
  507.                             SetMenuItemText(WindowsMenuH, WindowsMenuItems - 1 + WindowNum, TextTitle);
  508.                         end;
  509.             end;
  510.     end;
  511.  
  512.  
  513.     procedure SaveTextUsingPath(name:str255);
  514.     var
  515.         SaveTitle:str255;
  516.     begin
  517.         if TextInfo <> nil then with TextInfo^ do begin
  518.             SaveTitle:=TextTitle;
  519.             TextTitle := name;
  520.             TextRefNum := 0;
  521.             DoSaveText;
  522.             TextTitle:=SaveTitle;
  523.         end;
  524.     end;
  525.     
  526.     
  527.     procedure SaveText;
  528.     begin
  529.         if TextInfo <> nil then begin
  530.                 with TextInfo^ do
  531.                     if (TextRefNum = 0) or TooBig then
  532.                         SaveTextAs
  533.                     else
  534.                         DoSaveText;
  535.             end;
  536.     end;
  537.  
  538.  
  539.     function SaveTextChanges: integer;
  540.         const
  541.             yesID = 1;
  542.             NoID = 2;
  543.             CancelID = 3;
  544.         var
  545.             id: integer;
  546.             reply: SFReply;
  547.     begin
  548.         id := 0;
  549.         with TextInfo^ do
  550.             if changes and not TooBig then begin
  551.                     if macro and (MacroCommand = DisposeC) then begin
  552.                             SaveTextChanges := ok;
  553.                             exit(SaveTextChanges);
  554.                         end;
  555.                     ParamText(TextTitle, '', '', '');
  556.                     InitCursor;
  557.                     id := alert(600, nil);
  558.                     if id = yesID then
  559.                         SaveText;
  560.                 end; {if changes}
  561.         if id = cancelID then
  562.             SaveTextChanges := cancel
  563.         else
  564.             SaveTextChanges := ok;
  565.     end;
  566.  
  567.  
  568. procedure InsertText (str: str255; EndOfLine: boolean);
  569.   var
  570.    text: Ptr;
  571.    len: LongInt;
  572.  begin
  573.   if TextInfo <> nil then
  574.    with TextInfo^ do
  575.     begin
  576.      if EndOfLine then
  577.      str := concat(str, cr);
  578.      len := length(str);
  579.      if (TextTE^^.TELength + len) > 32767 then begin
  580.        AbortMacro;
  581.        exit(InsertText);
  582.      end;
  583.      if len > 0 then
  584.       begin
  585.        TEDelete(TextTE);
  586.        text := Ptr(Ord4(@str) + 1);
  587.        TEInsert(text, len, TextTE);
  588.        Changes := true;
  589.        UpdateScrollBars;
  590.        WhatToUndo := NothingToUndo;
  591.       end;
  592.     end;
  593.  end;
  594.  
  595.  
  596.  
  597.     procedure GoToLine (str: str255; data: CharArrayPtr);
  598.         var
  599.             pos, line: integer;
  600.             found: boolean;
  601.             n: LongInt;
  602.     begin
  603.         with TextInfo^.TextTE^^ do begin
  604.                 found := false;
  605.                 delete(str, 1, 1);
  606.                 StringToNum(str, n);
  607.                 pos := 0;
  608.                 line := 1;
  609.                 if n = 1 then
  610.                     found := true
  611.                 else
  612.                     repeat
  613.                         if data^[pos] = cr then
  614.                             line := line + 1;
  615.                         pos := pos + 1;
  616.                         if line = n then begin
  617.                                 found := true;
  618.                                 leave;
  619.                             end;
  620.                     until (pos >= teLength);
  621.                 if found then begin
  622.                         TESetSelect(pos, pos, TextInfo^.TextTE);
  623.                         TEKey('x', TextInfo^.TextTE);
  624.                         TEKey(BackSpace, TextInfo^.TextTE);
  625.                         UpdateScrollBars;
  626.                     end
  627.                 else
  628.                     beep;
  629.             end;
  630.     end;
  631.  
  632.  
  633.     procedure DoFind;
  634.         const
  635.             StringID = 3;
  636.         var
  637.             mylog: DialogPtr;
  638.             item: integer;
  639.             i, firstpos, lastpos, pos: integer;
  640.             slength: integer;
  641.             match: boolean;
  642.             data: CharArrayPtr;
  643.             c: char;
  644.             str: str255;
  645.     begin
  646.         if TextInfo = nil then
  647.             exit(DoFind);
  648.         hlock(handle(TextInfo^.TextTE));
  649.         with TextInfo^.TextTE^^ do begin
  650.                 if not OptionKeyWasDown then begin
  651.                         InitCursor;
  652.                         ParamText('What would you like to find?', '', '', '');
  653.                         mylog := GetNewDialog(170, nil, pointer(-1));
  654.                         SetDString(MyLog, StringID, SearchString);
  655.                         SelectdialogItemText(MyLog, StringID, 0, 32767);
  656.                         OutlineButton(MyLog, ok, 16);
  657.                         repeat
  658.                             ModalDialog(nil, item);
  659.                         until (item = ok) or (item = cancel);
  660.                         if item = cancel then begin
  661.                                 DisposeDialog(mylog);
  662.                                 exit(DoFind)
  663.                             end;
  664.                         SearchString := GetDString(MyLog, StringID);
  665.                         DisposeDialog(mylog);
  666.                     end;
  667.                 slength := Length(SearchString);
  668.                 if slength = 0 then
  669.                     exit(DoFind);
  670.                 str := SearchString;
  671.                 MakeLowerCase(str);
  672.                 data := CharArrayPtr(htext^);
  673.                 if (slength > 1) and (str[1] = '#') and (str[2] >= '0') and (str[2] <= '9') then begin
  674.                         GoToLine(str, data);
  675.                         hunlock(handle(TextInfo^.TextTE));
  676.                         exit(DoFind);
  677.                     end;
  678.                 match := false;
  679.                 lastpos := teLength - slength - 1;
  680.                 match := false;
  681.                 for firstpos := selEnd to lastpos do begin
  682.                         match := true;
  683.                         for i := 1 to slength do begin
  684.                                 c := data^[firstpos + i - 1];
  685.                                 if (c >= 'A') and (c <= 'Z') then
  686.                                     c := chr(ord(c) + 32);
  687.                                 if c <> str[i] then begin
  688.                                         match := false;
  689.                                         leave
  690.                                     end;
  691.                             end;
  692.                         if match then begin
  693.                                 pos := firstpos;
  694.                                 leave;
  695.                             end;
  696.                     end;
  697.                 if match then begin
  698.                         TESetSelect(pos, pos, TextInfo^.TextTE);
  699.                         TEKey('x', TextInfo^.TextTE);
  700.                         TEKey(BackSpace, TextInfo^.TextTE);
  701.                         TESetSelect(pos, pos + slength, TextInfo^.TextTE);
  702.                         UpdateScrollBars;
  703.                     end
  704.                 else
  705.                     beep;
  706.             end; {with}
  707.         hunlock(handle(TextInfo^.TextTE));
  708.     end;
  709.     
  710.     
  711.     procedure SelectAllText;
  712.     begin
  713.         if TextInfo<>nil then
  714.             TESetSelect(0, TextInfo^.TextTE^^.TELength, TextInfo^.TextTE)
  715.     end;
  716.  
  717.  
  718.  
  719. end.